package com.lnking.lnkingplace.service.impl;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.lnking.lnkingplace.Util.IdCardUtil;
import com.lnking.lnkingplace.Util.LocalDateTimeUtil;
import com.lnking.lnkingplace.Util.UserUtil;
import com.lnking.lnkingplace.mapper.PersonalCheckInfoMapper;
import com.lnking.lnkingplace.mapper.RecordUserMapper;
import com.lnking.lnkingplace.model.dto.place.PlaceSituationDto;
import com.lnking.lnkingplace.model.dto.recordUser.RecordDetailDto;
import com.lnking.lnkingplace.model.dto.recordUser.RecordUserNewTimeDto;
import com.lnking.lnkingplace.model.dto.recordUser.RecordUserSituationDto;
import com.lnking.lnkingplace.model.dto.user.UserDetailDto;
import com.lnking.lnkingplace.model.dto.user.UserDto;
import com.lnking.lnkingplace.model.entity.*;
import com.lnking.lnkingplace.model.request.record.user.RecordUserAddRequest;
import com.lnking.lnkingplace.model.request.record.user.RecordUserUpdateRequest;
import com.lnking.lnkingplace.service.*;
import com.lnking.starter.mybatis.mapper.CustomBaseMapper;
import com.lnking.starter.mybatis.service.impl.CustomServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author sn
 * @since 2022-08-18
 */
@Service
public class RecordUserServiceImpl extends CustomServiceImpl<RecordUserMapper, RecordUser> implements IRecordUserService {

    public static final String PRO="00.00%";
    public static final String TRUE="是";
    public static final String FALSE="否";
    public static final String FROMSYSTEM="数据接入";
    public static final String FROMUSER="手动填报";
    @Autowired
    IUserService userService;

    @Autowired
    INucleicAcidSetService nucleicAcidSetService;

    @Autowired
    UserUtil userUtil;

    @Autowired
    IPlaceInfoService placeInfoService;

    @Autowired
    IPersonalCheckInfoService personalCheckInfoService;

    @Override
    public void add(RecordUserAddRequest params) throws Exception{
        RecordUser entity = new RecordUser();
        BeanUtils.copyProperties(params, entity);
        entity.setCreatorTime(LocalDateTime.now());
        entity.setDataSources(FROMUSER);
            getBaseMapper().insert(entity);
    }

    @Override
    public void update(RecordUserUpdateRequest params) {
        RecordUser entity = new RecordUser();
        BeanUtils.copyProperties(params, entity);
        getBaseMapper().updateById(entity);
    }

    @Override
    public RecordDetailDto getUserDetailById(String id) {
        RecordUser recordUser = getBaseMapper().selectById(id);
        UserDetailDto userDetailById = userService.getUserDetailById(recordUser.getUserId());
        RecordDetailDto dto=new RecordDetailDto();
        BeanUtils.copyProperties(recordUser,dto);
        BeanUtils.copyProperties(userDetailById,dto);
        return dto;
    }

    @Override
    public RecordUserSituationDto situation() {

        RecordUserSituationDto dto=new RecordUserSituationDto();
        // 获取核酸判断时间类型
        UserDto user = userUtil.getUser();
        NucleicAcidSet nucleicAcidSet = nucleicAcidSetService.find(user.getId());
        // 根据渠道查询从业人员核酸情况
       List<RecordUserNewTimeDto> recordUserList = getBaseMapper().situation(user.getChannel());
       // 根据核酸判断时间类型来计算核酸检测达标率
        LocalDateTime minusTime = LocalDateTime.now().minusDays(nucleicAcidSet.getType());
        List<RecordUserNewTimeDto> qualifiedList = recordUserList.stream().filter(e -> e.getResultTime().isAfter(minusTime)).collect(Collectors.toList());
         // 整体合格率
        dto.setAllUserPercentage(percentage(qualifiedList.size(),recordUserList.size()));

        // 场所合格率
        // 1.获取该渠道下所有场所
        // 2.从目前防疫信息查询自己场所人员
        // 3.从合格核酸信息查询自己场所人员
        // 4.获取概率写入

        //1
        QueryWrapper<PlaceInfo> Swapper = new QueryWrapper<>();
        Swapper.lambda().eq(PlaceInfo::getChannel,user.getChannel());
        List<PlaceInfo> placeInfoList = placeInfoService.getBaseMapper().selectList(Swapper);

        List<PlaceSituationDto> placeSituationDtoList=new ArrayList<>();

        placeInfoList.forEach(e->{
            PlaceSituationDto placeSituationDto=new PlaceSituationDto();
            //2
            int all = recordUserList.stream().filter(e1 -> e1.getPlaceId().equals(e.getId())).collect(Collectors.toList()).size();
            //3
            int qualified = qualifiedList.stream().filter(e1 -> e1.getPlaceId().equals(e.getId())).collect(Collectors.toList()).size();
            //4
            String percentage = percentage(qualified, all);
            placeSituationDto.setPlaceName(e.getPlaceName());
            placeSituationDto.setRecordUserPercentage(percentage);
            // 目前只展示有数据的场所
            if(!percentage.equals(PRO)){
                placeSituationDtoList.add(placeSituationDto);
            }


        });
        dto.setPlaceSituationDtoList(placeSituationDtoList);
        return dto;
    }


    public RecordUser byCreatorTime(LocalDateTime time,String userId) {
        QueryWrapper<RecordUser> wapper =new QueryWrapper<>();
        wapper.lambda().eq(RecordUser::getUserId,userId);
        wapper.lambda().eq(RecordUser::getCreatorTime,time);
        wapper.lambda().eq(RecordUser::getDataSources,"数据接入");
        return getBaseMapper().selectOne(wapper);
    }

    @Override
    public void write() {
        // 获取身份证
        List<String> strings = iCard();
        // 写入前置数据库
        addIdCard(strings);

    }

    @Override
    public void read() {
        // 获取前置库数据
        List<PersonalCheckInfo> list = personalCheckInfoService.list();

        for (PersonalCheckInfo personalCheckInfo : list) {
            // 1.通过身份证找到人员信息
            List<User> userList=userService.findByIdCard(personalCheckInfo.getIdCardNo());
            List<RecordUser> recordUserList =new ArrayList<>();
            for (User user : userList) {
                if(user!=null&&(personalCheckInfo.getLastReportTime()!=null||personalCheckInfo.getLastCheckTime()!=null)){
                    // 2.写入人员防疫 根据采样时间判断今日是否核酸
                    // 根据 报告时间查询系统中是否以及存在
                    RecordUser  recordUserByCreatorTime= byCreatorTime(personalCheckInfo.getLastReportTime(), user.getId());
                   if(recordUserByCreatorTime==null){
                       RecordUser recordUser = new RecordUser();
                       recordUser.setUserId(user.getId());
                       recordUser.setCreatorTime(personalCheckInfo.getLastReportTime());
                       recordUser.setResultTime(personalCheckInfo.getLastReportTime());
                       recordUser.setResultStatus(personalCheckInfo.getReportResult());
                       recordUser.setCheckTime(personalCheckInfo.getLastCheckTime());
                       recordUser.setDataSources(FROMSYSTEM);
                       // 最后采样时间是否在今天
                       if(personalCheckInfo.getLastCheckTime()!=null){
                           if(LocalDateTimeUtil.isOnToday(personalCheckInfo.getLastCheckTime())){
                               recordUser.setCheckStatus(TRUE);
                           }else{
                               recordUser.setCheckStatus(FALSE);
                           }
                       }
                       recordUserList.add(recordUser);
                   }
                }
            }
            saveBatch(recordUserList);

        }

    }

    // 获取身份证
    public  List<String> iCard(){
        List<UserDto> list=new ArrayList<>();
        list = ((CustomBaseMapper) userService.getBaseMapper()).customSelectList(null);
        // 身份证不能为空
        List<UserDto> userDtoList = list.stream().filter(e -> StringUtils.isNotBlank(e.getDesensitizationIdCard())).collect(Collectors.toList());
        //  没有防疫上报记录的另外计算
        List<UserDto> userDtos = userDtoList.stream().filter(e -> e.getDiffDate() != null).collect(Collectors.toList());
        List<String> collect = userDtos.stream().filter(e ->  (e.getConfigDay() - e.getDiffDate()) <= 24).map(UserDto::getDesensitizationIdCard).collect(Collectors.toList());
        // 把没有防疫记录的添加到list
        collect.addAll(userDtoList.stream().filter(e -> e.getDiffDate() == null).map(UserDto::getDesensitizationIdCard).collect(Collectors.toList()));
        // 验证身份证 并去重
        List<String> idCardList = collect.stream().filter(e -> IdCardUtil.isIdcard(e)).distinct().collect(Collectors.toList());
        // 把x切换成大写
        List<String> idCards = idCardList.stream().map(e -> e.toUpperCase()).collect(Collectors.toList());
        return idCards;
    }

    public void addIdCard(List<String> idCards){
        List<PersonalCheckInfo> list = personalCheckInfoService.list();
        List<String> stringList = list.stream().map(PersonalCheckInfo::getIdCardNo).collect(Collectors.toList());
        List<String>  strings =new ArrayList<>();
        // 删除重复
        for (String idCard : idCards) {
            // 获取数据库中不包含的
            if (!stringList.contains(idCard)) {
                strings.add(idCard);
            }

        }
        List<PersonalCheckInfo> collect = strings.stream().map(e -> new PersonalCheckInfo(e, null, null, null)).collect(Collectors.toList());
        personalCheckInfoService.saveBatch(collect);
    }


    public static String percentage(Integer molecule, Integer denominator){
        //创建一个数值格式化对象
        java.text.NumberFormat numberformat=java.text.NumberFormat.getInstance();
        //设置精确到小数点后2位
        numberformat.setMaximumFractionDigits(2);
        if(0 == molecule){
            return PRO;
        }
        return numberformat.format((float)molecule/(float)denominator*100)+"%";
    }
}
